package com.fangs.yehwangglobal.base

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.fangs.yehwangglobal.R
import com.fangs.yehwangglobal.utils.ActivityUtils
import com.fangs.yehwangglobal.widget.eventbus.BindEventBus
import com.fangs.yehwangglobal.widget.eventbus.EventManager
import com.fangs.yehwangglobal.widget.loading.LoadingPopup
import com.gyf.immersionbar.ImmersionBar
import com.hjq.language.MultiLanguages
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.ParameterizedType

abstract class BaseActivity<VB : ViewBinding?> : AppCompatActivity() {

    protected var viewBinding: VB? = null
    private var loadingPopup: LoadingPopup? = null//网络请求时的背景透明不遮挡页面小进度提示  需要时显示
    private val handler = Handler()
    private val runnable = label@ Runnable {
        if (currentFocus != null && currentFocus is EditText) {
            return@Runnable
        }
        hideKeyboard()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val type = javaClass.genericSuperclass as ParameterizedType
        val cls = type.actualTypeArguments[0] as Class<*>
        try {
            val inflate = cls.getDeclaredMethod("inflate", LayoutInflater::class.java)
            viewBinding = inflate.invoke(null, layoutInflater) as VB
            setContentView(viewBinding?.getRoot())
        } catch (e: NoSuchMethodException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        } catch (e: InvocationTargetException) {
            e.printStackTrace()
        }
        if (this.javaClass.isAnnotationPresent(BindEventBus::class.java)) {
            EventManager.register(this)
        }

        if (needImmersionBar()) {
            //状态栏字体是深色，不写默认为亮色
            ImmersionBar.with(this)
                .statusBarDarkFont(statusBarDarkFont()) //状态栏字体是深色，不写默认为亮色
                .fitsSystemWindows(fitsSystemWindows()).init()
        }
        afterCreate(savedInstanceState)
        ActivityUtils.addActivity(this)
    }

    protected abstract fun afterCreate(savedInstanceState: Bundle?)

    fun showLoadingAtLocation(root: View?) {
        if (loadingPopup == null) {
            loadingPopup = LoadingPopup.Companion.getInstance(this)
        }
        loadingPopup?.showNow(root!!)
    }

    fun dismissLoadingPopup() {
        if (loadingPopup != null) {
            loadingPopup?.dismissNow()
        }
    }

    fun hideKeyboard() {
        if (currentFocus != null && currentFocus!!.windowToken != null) {
            val im = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
            im.hideSoftInputFromWindow(
                currentFocus!!.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }
        if (currentFocus == null) {
            val im = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
            im.hideSoftInputFromWindow(
                window.decorView.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }
    }

    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(MultiLanguages.attach(newBase))
    }

    /**
     * 是否需要沉浸式状态栏
     */
    fun needImmersionBar(): Boolean {
        return true
    }

    /**
     * 沉浸式状态栏颜色
     */
    fun statusBarDarkFont(): Boolean {
        return true
    }

    /**
     * 沉浸式状态栏是否布局适配系统窗口（保留系统顶部栏空间）
     */
    fun fitsSystemWindows(): Boolean {
        return true
    }

    /**
     * Created by ivan.cai on 2019/7/26.
     * 加上通用的转场动画 以搭配侧滑返回效果
     */
    override fun startActivity(intent: Intent?) {
        super.startActivity(intent)
        overridePendingTransition(R.anim.fade_right_in, R.anim.fade_left_out)
    }

    /**
     * Created by ivan.cai on 2019/7/26.
     * 加上通用的转场动画 以搭配侧滑返回效果
     */
    override fun finish() {
        super.finish()
        overridePendingTransition(R.anim.fade_left_in, R.anim.fade_right_out)
    }

    override fun onDestroy() {
        super.onDestroy()
        if (this.javaClass.isAnnotationPresent(BindEventBus::class.java)) {
            EventManager.unregister(this)
        }
        dismissLoadingPopup()
        ActivityUtils.removeActivity(this)
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN) {
            val v = currentFocus
            if (isShouldHideKeyboard(v, ev)) {
                handler.removeCallbacks(runnable)
                v!!.clearFocus()
                handler.postDelayed(
                    runnable,
                    200
                ) // 笨方法 采用延迟策略 避免界面多个Edittext时 点击下个EditText 软键盘会出现先隐藏后弹出情形
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时则不能隐藏
     */
    private fun isShouldHideKeyboard(v: View?, event: MotionEvent): Boolean {
        if (v is EditText) {
            val l = intArrayOf(0, 0)
            v.getLocationInWindow(l)
            val left = l[0]
            val top = l[1]
            val bottom = top + v.getHeight()
            val right = left + v.getWidth()
            return (event.x <= left || event.x >= right
                    || event.y <= top || event.y >= bottom)
        }
        // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，第一个焦点不在EditText上，和用户用轨迹球选择其他的焦点
        return false
    }
}